/*
 * xo-download.h
 *
 *  Created on: Aug 4, 2010
 *      Author: forhappy
 */

#ifndef XO_DOWNLOAD_H_
#define XO_DOWNLOAD_H_
#include <pthread.h>

#include <signal.h>
enum {
	GETREQSIZ = 256,
	GETRECVSIZ = 8192,
	HEADREQSIZ = 512,
	MAXURLSIZ = 1024,
	MAXHOSTSIZ = 1024,
	MAXIPSIZ = 16,
	MAXBUFSIZ = 512,
	MAXTHREADS = 25,
	HTTPPORT = 80,
	UNKNOWNREQ = 2,
	FTPREQ = 21,
	PROTO_HTTP = 0xFF,
	PROTO_FTP = 0x00,
	STAT_OK = 0xFF,		/* Download completed successfully	*/
	STAT_INT = 0x0F,	/* ^C caught, download interrupted	*/
	STAT_ERR = 0x00		/* Download finished with error		*/
};
#define _XOPEN_SOURCE 500
typedef struct request {
	char host[MAXHOSTSIZ];		/* Remote host	*/
	char url[MAXURLSIZ];		/* URL		*/
	char file[MAXBUFSIZ];		/* file name	*/
	char lfile[MAXBUFSIZ];		/* if local file name is specified	*/
	char ip[MAXIPSIZ];		/* Remote IP	*/
	char username[MAXBUFSIZ];
	char password[MAXBUFSIZ];
	int port;
	long long clength;		/* Content-length	*/
	unsigned char proto;		/* Protocol		*/
} request;

typedef struct thread_data {
	struct sockaddr_in sin;
	char getstr[GETREQSIZ];
	long long soffset;		/* Start offset		*/
	long long foffset;		/* Finish offset	*/
	long long offset;		/* Current Offset	*/
	long long clength;		/* Content Length	*/
	int fd;
	pthread_t tid;		/* Thread ID		*/
	unsigned char status;	/* thread exit status	*/
} thread_data;

char *fullurl;

int nthreads;
int fsuggested = 0;
unsigned int bwritten = 0;
pthread_mutex_t bwritten_mutex = PTHREAD_MUTEX_INITIALIZER;

struct request *req;		/* Download jobs		*/
pthread_t hthread;		/* Helper thread for signals	*/
struct thread_data *wthread;	/* Worker Threads		*/

#define	LOGSIZ	1024

int calc_offset(long long, int, int);
int numofthreads(int);
void parse_url(char *, struct request *);
void usage();
void revstr(char *);				/* Reverse String				*/
void Log(char *, ...);				/* Log 						*/
void updateProgressBar(float, float);
void handleHttpRetcode(char *);

time_t  t_start, t_finish;

typedef struct hist_data {
	struct request req;
	int nthreads;
	int bwritten;
	struct thread_data wthread[MAXTHREADS];
} hist_data;

void save_log();
int read_log(struct hist_data *);

sigset_t signal_set;

void * signal_waiter(void *arg);
void sigint_handler(void);
void sigalrm_handler(void);


#define	PROGVERSION  "EnderUNIX Aget v0.4.1"
#define	HEADREQ  "HEAD %s HTTP/1.1\r\nHost: %s\r\nUser-Agent: %s\r\n\r\n"
#define	GETREQ  "GET %s HTTP/1.1\r\nHost: %s\r\nUser-Agent: %s\r\nRange: bytes=%lld-\r\nConnection: close\r\n\r\n"

void get(struct request *);
void resume_get(struct hist_data *);
void * http_get(void *);
void http_head_req(struct request *);

#endif /* XO_DOWNLOAD_H_ */
